﻿@using Aspire.Dashboard.Components.Controls.Grid
@using Aspire.Dashboard.Components.Controls.PropertyValues
@using Aspire.Dashboard.Model
@using Aspire.Dashboard.Resources
@using Aspire.Dashboard.Utils
@using Humanizer
@using Microsoft.Extensions.Diagnostics.HealthChecks
@using Aspire.Dashboard.Model.Otlp

@inject IStringLocalizer<ControlsStrings> ControlStringsLoc
@inject IStringLocalizer<Resources> Loc

<div class="resource-details-layout">

    <FluentToolbar Orientation="Orientation.Horizontal">
        <FluentAnchor Appearance="Appearance.Lightweight" Href="@DashboardUrls.ConsoleLogsUrl(ResourceViewModel.GetResourceName(Resource, ResourceByName))" slot="end">@Loc[nameof(Resources.ResourceDetailsViewConsoleLogs)]</FluentAnchor>

        @if (ShowSpecOnlyToggle)
        {
            <FluentIconSwitch Appearance="Appearance.Lightweight"
                              Disabled="IsSpecOnlyToggleDisabled"
                              CheckedTitle="@ControlStringsLoc[nameof(ControlsStrings.EnvironmentVariablesFilterToggleShowSpecOnly)]"
                              UncheckedTitle="@ControlStringsLoc[nameof(ControlsStrings.EnvironmentVariablesFilterToggleShowAll)]"
                              OnToggle="@(() => _showAll = !_showAll)"
                              CheckedIcon="@(new Icons.Regular.Size16.DocumentHeader())"
                              UncheckedIcon="@(new Icons.Regular.Size16.DocumentOnePage())"
                              slot="end"/>
        }

        <FluentIconSwitch @bind-Value="@IsMaskAllChecked"
                          Appearance="Appearance.Lightweight"
                          CheckedTitle="@ControlStringsLoc[nameof(ControlsStrings.EnvironmentVariablesShowVariableValues)]"
                          UncheckedTitle="@ControlStringsLoc[nameof(ControlsStrings.EnvironmentVariablesHideVariableValues)]"
                          OnToggle="@OnMaskAllCheckedChanged"
                          CheckedIcon="@(new Icons.Regular.Size16.Eye())"
                          UncheckedIcon="@(new Icons.Regular.Size16.EyeOff())"
                          class="mask-all-switch"
                          slot="end" />

        <FluentSearch Placeholder="@ControlStringsLoc[nameof(ControlsStrings.FilterPlaceholder)]"
                      Immediate="true"
                      Autofocus="true"
                      @bind-Value="_filter"
                      slot="end" />
    </FluentToolbar>
    <div class="property-grid-container">
        <FluentAccordion>
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsResourceHeader)]" Expanded="true">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredResourceProperties.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="DisplayedResourcePropertyViewModel"
                              Items="@FilteredResourceProperties"
                              IsValueMaskedChanged="@OnValueMaskedChanged"
                              HighlightText="@_filter"
                              GridTemplateColumns="1fr 1.5fr"
                              ValueComponents="_valueComponents" />
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsUrlsHeader)]" Expanded="@_isUrlsExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredUrls.Count()
                    </FluentBadge>
                </div>
                <FluentDataGrid TGridItem="DisplayedUrl"
                                ItemKey="@(vm => ((IPropertyGridItem)vm).Key)"
                                Items="@FilteredUrls"
                                ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizableColumns="true"
                                ResizeType="DataGridResizeType.Discrete"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="1fr 1fr 0.5fr"
                                ShowHover="true">
                    <AspireTemplateColumn Sortable="true" SortBy="@_urlValueSort" Title="@ControlStringsLoc[nameof(ControlsStrings.LinkAddressColumnHeader)]">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.LinkAddressColumnHeader)]"
                                   Value="@context.OriginalUrlString"
                                   ValueTemplate="@(_ => RenderAddressValue(context, _filter))"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                   IsMaskedChanged="@(_ => OnValueMaskedChanged(context))"
                                   HighlightText="@_filter" />
                    </AspireTemplateColumn>
                    <AspireTemplateColumn Sortable="true" SortBy="@_urlValueSort" Title="@ControlStringsLoc[nameof(ControlsStrings.LinkTextColumnHeader)]">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.LinkTextColumnHeader)]"
                                   Value="@context.DisplayName"
                                   ValueTemplate="@(_ => RenderTextValue(context, _filter))"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter) && !string.IsNullOrEmpty(context.DisplayName))"
                                   IsMaskedChanged="@(_ => OnValueMaskedChanged(context))"
                                   HighlightText="@_filter" />
                    </AspireTemplateColumn>
                    <AspireTemplateColumn Sortable="true" SortBy="@(GridSort<DisplayedUrl>.ByAscending(i => i.Name))" Title="@ControlStringsLoc[nameof(ControlsStrings.EndpointNameColumnHeader)]">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.EndpointNameColumnHeader)]"
                                   Value="@context.Name"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                   HighlightText="@_filter" />
                    </AspireTemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
            @if (Resource.IsContainer())
            {
                <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsVolumesHeader)]" Expanded="@_isVolumesExpanded">
                    <div slot="end">
                        <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                            @FilteredVolumes.Count()
                        </FluentBadge>
                    </div>

                    <FluentDataGrid TGridItem="VolumeViewModel"
                                    ItemKey="@(vm => ((IPropertyGridItem)vm).Key)"
                                    Items="@FilteredVolumes"
                                    ColumnResizeLabels="@_resizeLabels"
                                    ColumnSortLabels="@_sortLabels"
                                    HeaderCellAsButtonWithMenu="true"
                                    ResizableColumns="true"
                                    ResizeType="DataGridResizeType.Discrete"
                                    Style="width:100%"
                                    RowSize="DataGridRowSize.Medium"
                                    GridTemplateColumns="1fr 1fr 0.5fr"
                                    ShowHover="true">
                        <AspireTemplateColumn Sortable="true" SortBy="@(GridSort<VolumeViewModel>.ByAscending(i => i.Source))" Title="@ControlStringsLoc[nameof(ControlsStrings.NameColumnHeader)]">
                            <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.NameColumnHeader)]"
                                       Value="@context.Source"
                                       EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                       HighlightText="@_filter" />
                        </AspireTemplateColumn>
                        <AspireTemplateColumn Sortable="true" SortBy="@(GridSort<VolumeViewModel>.ByAscending(i => i.Target))" Title="@ControlStringsLoc[nameof(ControlsStrings.VolumePathColumnHeader)]">
                            <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.VolumePathColumnHeader)]"
                                       Value="@context.Target"
                                       EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                       HighlightText="@_filter" />
                        </AspireTemplateColumn>
                        <AspireTemplateColumn Sortable="true" SortBy="@(GridSort<VolumeViewModel>.ByAscending(i => i.MountType))" Title="@ControlStringsLoc[nameof(ControlsStrings.VolumeMountTypeColumnHeader)]">
                            <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.VolumeMountTypeColumnHeader)]"
                                       Value="@context.MountType.Humanize()">
                                <ContentBeforeValue>
                                    @if (context.IsReadOnly)
                                    {
                                        <FluentIcon Value="@(new Icons.Regular.Size16.LockClosed())" Class="volume-mount-type-icon" />
                                    }
                                </ContentBeforeValue>
                            </GridValue>
                        </AspireTemplateColumn>
                    </FluentDataGrid>
                </FluentAccordionItem>
            }
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsReferences)]" Expanded="@_isRelationshipsExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredRelationships.Count()
                    </FluentBadge>
                </div>
                <FluentDataGrid ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizeType="DataGridResizeType.Discrete"
                                TGridItem="ResourceDetailRelationshipViewModel"
                                Items="@FilteredRelationships"
                                ItemKey="r => r.ResourceName"
                                ResizableColumns="true"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="1fr 1fr 0.5fr"
                                ShowHover="true">
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsResourceHeader)]">
                        <ResourceNameValue Resource="@context.Resource" Value="@context.ResourceName" FormatName="@FormatName" />
                    </TemplateColumn>
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsTypeHeader)]" TooltipText="@(c => string.Join(", ", c.Types))">
                        @string.Join(", ", context.Types)
                    </TemplateColumn>
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ViewAction)]" Class="no-ellipsis">
                        <FluentButton Appearance="Appearance.Lightweight" Class="button-hyperlink-no-icon" OnClick="@(() => OnViewRelationshipAsync(context))">@ControlStringsLoc[nameof(ControlsStrings.ViewAction)]</FluentButton>
                    </TemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsBackReferences)]" Expanded="@_isBackRelationshipsExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredBackRelationships.Count()
                    </FluentBadge>
                </div>
                <FluentDataGrid ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizeType="DataGridResizeType.Discrete"
                                TGridItem="ResourceDetailRelationshipViewModel"
                                Items="@FilteredBackRelationships"
                                ItemKey="r => r.ResourceName"
                                ResizableColumns="true"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="1fr 1fr 0.5fr"
                                ShowHover="true">
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsResourceHeader)]">
                        <ResourceNameValue Resource="@context.Resource" Value="@context.ResourceName" FormatName="@FormatName" />
                    </TemplateColumn>
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsTypeHeader)]" TooltipText="@(c => string.Join(", ", c.Types))">
                        @string.Join(", ", context.Types)
                    </TemplateColumn>
                    <TemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.ViewAction)]" Class="no-ellipsis">
                        <FluentButton Appearance="Appearance.Lightweight" Class="button-hyperlink-no-icon" OnClick="@(() => OnViewRelationshipAsync(context))">@ControlStringsLoc[nameof(ControlsStrings.ViewAction)]</FluentButton>
                    </TemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceHealthChecksHeader)]" Expanded="@_isHealthChecksExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredHealthReports.Count()
                    </FluentBadge>
                </div>

                <FluentDataGrid ColumnResizeLabels="@_resizeLabels"
                                ColumnSortLabels="@_sortLabels"
                                HeaderCellAsButtonWithMenu="true"
                                ResizeType="DataGridResizeType.Discrete"
                                Items="@FilteredHealthReports"
                                ItemKey="r => r.Name"
                                ResizableColumns="true"
                                Style="width:100%"
                                RowSize="DataGridRowSize.Medium"
                                GridTemplateColumns="1fr 1fr 1.5fr"
                                ShowHover="true">
                    <AspireTemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.NameColumnHeader)]" Class="nameColumn">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.NameColumnHeader)]"
                                   Value="@context.Name"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                   HighlightText="@_filter" />
                    </AspireTemplateColumn>
                    <AspireTemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.StateColumnHeader)]" Class="stateColumn">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.StateColumnHeader)]"
                                   Value="@(context.HealthStatus?.Humanize() ?? Loc[nameof(Resources.WaitingHealthDataStatusMessage)])"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                   HighlightText="@_filter"
                                   TextVisualizerTitle="@context.Name">
                            <ContentBeforeValue>
                                @if (context.HealthStatus is null)
                                {
                                    <FluentProgressRing Width="16px" Style="display: inline-block;" Class="severity-icon" />
                                }
                                else
                                {
                                    (Icon? icon, Color color) = ResourceIconHelpers.GetHealthStatusIcon(context.HealthStatus);

                                    <FluentIcon Value="@icon" Color="@color" Class="severity-icon"/>
                                }
                            </ContentBeforeValue>
                        </GridValue>
                    </AspireTemplateColumn>
                    <AspireTemplateColumn Title="@ControlStringsLoc[nameof(ControlsStrings.DetailsColumnHeader)]" Class="detailsColumn">
                        <GridValue ValueDescription="@ControlStringsLoc[nameof(ControlsStrings.DetailsColumnHeader)]"
                                   Value="@(context.HealthStatus is null ? Loc[nameof(Resources.WaitingForHealthDataMessage)] : context.DisplayedDescription)"
                                   EnableHighlighting="@(!string.IsNullOrEmpty(_filter))"
                                   HighlightText="@_filter"
                                   TextVisualizerTitle="@context.Name">
                            <ContentInButtonArea>
                                <ExceptionDetails ExceptionText="@context.ExceptionText" />
                            </ContentInButtonArea>
                        </GridValue>
                    </AspireTemplateColumn>
                </FluentDataGrid>
            </FluentAccordionItem>
            <FluentAccordionItem Heading="@ControlStringsLoc[nameof(ControlsStrings.ResourceDetailsEnvironmentVariablesHeader)]" Expanded="@_isEnvironmentVariablesExpanded">
                <div slot="end">
                    <FluentBadge Appearance="Appearance.Neutral" Circular="true">
                        @FilteredEnvironmentVariables.Count()
                    </FluentBadge>
                </div>
                <PropertyGrid TItem="EnvironmentVariableViewModel"
                              Items="@FilteredEnvironmentVariables"
                              IsValueMaskedChanged="@OnValueMaskedChanged"
                              HighlightText="@_filter"
                              GridTemplateColumns="1fr 1.5fr"
                              Class="env-var-properties" />
            </FluentAccordionItem>
        </FluentAccordion>
    </div>
</div>

@code {
    private static RenderFragment RenderAddressValue(DisplayedUrl vm, string filter)
    {
        var highlighting = !string.IsNullOrEmpty(filter);

        // If there's no URL, e.g. this is a tcp:// URI, just show the text
        if (vm.Url is null)
        {
            if (highlighting)
            {
                return @<FluentHighlighter HighlightedText="@filter" Text="@vm.Text" />;
            }
            return @<span>@vm.Text</span>;
        }
        // Otherwise, render a link for the URL
        else
        {
            if (highlighting)
            {
                return @<a href="@vm.Url" target="_blank"><FluentHighlighter HighlightedText="@filter" Text="@vm.Url" /></a>;
            }
            return @<a href="@vm.Url" target="_blank">@vm.Url</a>;
        }
    }

    private static RenderFragment RenderTextValue(DisplayedUrl vm, string filter)
    {
        var highlighting = !string.IsNullOrEmpty(filter) && !string.IsNullOrEmpty(vm.DisplayName);

        // If there's no DisplayName then show nothing
        if (string.IsNullOrEmpty(vm.DisplayName))
        {
            return @<span class="empty-data"></span>;
        }
        // Otherwise, render a link with the text as the anchor text & title as the URL
        else
        {
            if (highlighting)
            {
                return @<a href="@vm.Url" title="@vm.Url" target="_blank"><FluentHighlighter HighlightedText="@filter" Text="@vm.DisplayName" /></a>;
            }
            return @<a href="@vm.Url" title="@vm.Url" target="_blank">@vm.DisplayName</a>;
        }
    }
}
